{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "13HXx8JP8Unc",
        "outputId": "9d70cb31-5d76-42d5-ea34-540d29d83dae"
      },
      "outputs": [],
      "source": [
        "!pip install openai-agents sendgrid"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "U44m8Y6L77Vu"
      },
      "outputs": [],
      "source": [
        "from agents import Agent, Runner, trace, function_tool, ImageGenerationTool, RunContextWrapper\n",
        "import os\n",
        "import asyncio\n",
        "from typing import TypedDict, Dict\n",
        "from pydantic import Field, BaseModel\n",
        "from sendgrid import SendGridAPIClient\n",
        "from sendgrid.helpers.mail import Mail, Email, To, Content, Attachment, FileContent, FileName, FileType, Disposition, ContentId\n",
        "\n",
        "from google.colab import userdata\n",
        "\n",
        "os.environ['OPENAI_API_KEY'] = userdata.get('OPENAI_API_KEY')\n",
        "os.environ['SENDGRID_API_KEY'] = userdata.get('SENDGRID_API_KEY')\n",
        "\n",
        "from agents import set_tracing_export_api_key\n",
        "\n",
        "set_tracing_export_api_key(os.getenv(\"OPENAI_API_KEY\"))\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "rz0JkAYI7qdh"
      },
      "outputs": [],
      "source": [
        "# Improved instructions thanks to student Guillermo F.\n",
        "instructions1 = \"You are a sales agent working for ComplAI, \\\n",
        "a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\n",
        "You write professional, serious cold emails.\"\n",
        "\n",
        "instructions2 = \"You are a humorous, engaging sales agent working for ComplAI, \\\n",
        "a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\n",
        "You write witty, engaging cold emails that are likely to get a response.\"\n",
        "\n",
        "instructions3 = \"You are a busy sales agent working for ComplAI, \\\n",
        "a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\n",
        "You write concise, to the point cold emails.\"\n",
        "\n",
        "description = \"Write a cold sales email\"\n",
        "\n",
        "sales_agent1 = Agent(\n",
        "        name=\"Professional Sales Agent\",\n",
        "        instructions=instructions1,\n",
        "        model=\"gpt-4o-mini\",\n",
        ")\n",
        "\n",
        "sales_agent2 = Agent(\n",
        "        name=\"Engaging Sales Agent\",\n",
        "        instructions=instructions2,\n",
        "        model=\"gpt-4o-mini\",\n",
        ")\n",
        "\n",
        "sales_agent3 = Agent(\n",
        "        name=\"Busy Sales Agent\",\n",
        "        instructions=instructions3,\n",
        "        model=\"gpt-4o-mini\",\n",
        ")\n",
        "sales_manager_instructions = \"\"\"\n",
        "You are a Sales Manager at ComplAI. Your goal is to find the best cold sales email of the generated mails using the sales_agent tools.\n",
        "\n",
        "Follow these steps carefully:\n",
        "1. Generate Drafts: Use all three sales_agent tools to generate three different email drafts. Do not proceed until all three drafts are ready. Do not execute them more than once.\n",
        "\n",
        "2. Evaluate and Select: Review the drafts and choose the single best email using your judgment of which one is most effective.\n",
        "\n",
        "3. Handoff for Sending: Pass ONLY the winning email draft to the 'Email Manager' agent. The Email Manager will take care of formatting and sending.\n",
        "\n",
        "Crucial Rules:\n",
        "- You must use the sales agent tools to generate the drafts — do not write them yourself.\n",
        "- You must output exactly ONE email — never more than one.\n",
        "\"\"\"\n",
        "tool1 = sales_agent1.as_tool(tool_name=\"sales_agent1\", tool_description=description)\n",
        "tool2 = sales_agent2.as_tool(tool_name=\"sales_agent2\", tool_description=description)\n",
        "tool3 = sales_agent3.as_tool(tool_name=\"sales_agent3\", tool_description=description)\n",
        "\n",
        "tools = [tool1, tool2, tool3]\n",
        "\n",
        "sales_manager = Agent(\n",
        "    name=\"Sales Manager\",\n",
        "    instructions=sales_manager_instructions,\n",
        "    tools=tools,\n",
        "    #handoffs=handoffs,\n",
        "    model=\"gpt-4o-mini\")\n",
        "\n",
        "image_generation_tool = ImageGenerationTool(\n",
        "    tool_config={\n",
        "        'type': 'image_generation',\n",
        "        'quality': 'low',  # Options: 'low', 'medium', 'high', 'auto'\n",
        "        'size': '1024x1024',  # Or '1024x1536', '1536x1024', 'auto'\n",
        "        'output_format': 'png',  # Or 'webp', 'jpeg'\n",
        "    }\n",
        ")\n",
        "\n",
        "image_agent = Agent(name='Image_Generator',\n",
        "                        instructions=\"You will create a small image that goes well with the email attached using your image_generation_tool.\",                        model=\"gpt-4o\",\n",
        "                        tools=[image_generation_tool],\n",
        "                        )\n",
        "\n",
        "html_instructions = \"\"\"You are given a text email body which might have some markdown \\\n",
        "and you need to convert it to an HTML email body with simple, clear, compelling layout and design.\\\n",
        "Your output should strictly be the body in HTML format (without ```html nor ```), including the tag <img src=\"cid:my_image\" alt=\"My Image\" />\"\"\"\n",
        "html_converter = Agent(name=\"HTML email body converter\", instructions=html_instructions, model=\"gpt-4o-mini\")\n",
        "\n",
        "class Ctx(BaseModel):\n",
        "    html_body: str\n",
        "    img_64: str\n",
        "\n",
        "    def __getitem__(self, key: str):\n",
        "        return self.model_dump()[key]\n",
        "\n",
        "@function_tool\n",
        "def send_html_tool(ctx: RunContextWrapper[Ctx])-> Dict[str, str]:\n",
        "    \"\"\"\n",
        "    Send an HTML email with an embedded image.\n",
        "\n",
        "    Args:\n",
        "        ctx: Dictionary containing 'html_body' (HTML content) and 'img_64' (base64 encoded image)\n",
        "\n",
        "    Returns:\n",
        "        Dictionary with 'status' indicating success\n",
        "    \"\"\"\n",
        "    context_dict = ctx.context\n",
        "\n",
        "    html_body = context_dict[\"html_body\"]\n",
        "    encoded_image = context_dict[\"img_64\"]\n",
        "\n",
        "    sg = SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))\n",
        "\n",
        "    message = Mail(\n",
        "        from_email=Email(\"javier.otero.marquez@gmail.com\"),\n",
        "        to_emails=To(\"javiomotero@gmail.com\"),\n",
        "        subject=\"Your Message\",\n",
        "        html_content=html_body\n",
        "    )\n",
        "    attachment = Attachment(\n",
        "        FileContent(encoded_image),\n",
        "        FileName('image.jpg'),\n",
        "        FileType('image/jpeg'),\n",
        "        Disposition('inline'),\n",
        "        ContentId('my_image')\n",
        "    )\n",
        "\n",
        "    message.add_attachment(attachment)\n",
        "\n",
        "    response = sg.send(message)\n",
        "    return {\"status\": \"success\"}\n",
        "\n",
        "mailer_instructions =\"You are an email sender. Use send_html_tool to send the prepared email. All required data is already available in context.\"\n",
        "emailer_agent = Agent(\n",
        "    name=\"Email Manager\",\n",
        "    instructions=mailer_instructions,\n",
        "    tools=[send_html_tool],\n",
        "    model=\"gpt-4o-mini\",\n",
        "    )\n",
        "message = \"Send out a cold sales email addressed to Dear CEO from Alice\"\n",
        "\n",
        "with trace(\"Automated SDR\"):\n",
        "    best_mail_result = await Runner.run(sales_manager, message)\n",
        "    best_mail_str = best_mail_result.final_output\n",
        "    image_result = await Runner.run(image_agent, best_mail_str)\n",
        "    img_64_str = image_result.raw_responses[0].output[0].result\n",
        "\n",
        "    html_body = await Runner.run(html_converter, best_mail_str)\n",
        "    html_body_str = html_body.final_output\n",
        "    emailer = await Runner.run(\n",
        "        starting_agent=emailer_agent,\n",
        "        input=\"Use your send_html_tool to send the prepared email with the image.\",\n",
        "        context=Ctx(html_body=html_body_str, img_64=img_64_str)\n",
        "    )\n"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
